From: Florian Müllner Date: Sat, 10 Jun 2017 02:14:12 +0000 (+0200) Subject: environment: Add convenience method for property transitions X-Git-Tag: archive/raspbian/50.5-1+rpi1~1^2~839^2^2~47 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/%22/%22http:/www.example.com/cgi/%22?a=commitdiff_plain;h=ef18f621ac58c6ce3071572751584b7e6f833d90;p=gnome-shell.git environment: Add convenience method for property transitions While we are now using implicit animations for all animatable properties, there are still some cases where we animate other actor properties (for example from a custom subclass) or associated objects like effects. Those can still be animated using Clutter animations, as long as we use the explicit API rather than implicit animations. Again this API is cumbersome and tricky enough to warrant a convenience wrapper. https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/666 --- diff --git a/js/ui/environment.js b/js/ui/environment.js index d36521736..b00b74dd9 100644 --- a/js/ui/environment.js +++ b/js/ui/environment.js @@ -90,6 +90,25 @@ function _makeEaseCallback(params) { }; } +function _getPropertyTarget(actor, propName) { + if (!propName.startsWith('@')) + return [actor, propName]; + + let [type, name, prop] = propName.split('.'); + switch (type) { + case '@layout': + return [actor.layout_manager, name]; + case '@actions': + return [actor.get_action(name), prop]; + case '@constraints': + return [actor.get_constraint(name), prop]; + case '@effects': + return [actor.get_effect(name), prop]; + } + + throw new Error(`Invalid property name ${propName}`); +} + function _easeActor(actor, params) { actor.save_easing_state(); @@ -125,6 +144,45 @@ function _easeActor(actor, params) { actor.restore_easing_state(); } +function _easeActorProperty(actor, propName, target, params) { + // Avoid pointless difference with ease() + if (params.mode) + params.progress_mode = params.mode; + delete params.mode; + + if (params.duration) + params.duration = adjustAnimationTime(params.duration); + let duration = Math.floor(params.duration || 0); + + let callback = _makeEaseCallback(params); + + // cancel overwritten transition + actor.remove_transition(propName); + + if (duration == 0) { + let [obj, prop] = _getPropertyTarget(actor, propName); + obj[prop] = target; + + if (callback) + callback(true); + + return; + } + + let pspec = actor.find_property(propName); + let transition = new Clutter.PropertyTransition(Object.assign({ + property_name: propName, + interval: new Clutter.Interval({ value_type: pspec.value_type }), + remove_on_complete: true + }, params)); + actor.add_transition(propName, transition); + + transition.set_to(target); + + if (callback) + _trackTransition(transition, callback); +} + function _loggingFunc(...args) { let fields = { 'MESSAGE': args.join(', ') }; let domain = "GNOME Shell"; @@ -173,6 +231,9 @@ function init() { Clutter.Actor.prototype.ease = function(props, easingParams) { _easeActor(this, props, easingParams); }; + Clutter.Actor.prototype.ease_property = function(propName, target, params) { + _easeActorProperty(this, propName, target, params); + }; Clutter.Actor.prototype.toString = function() { return St.describe_actor(this);